package com.chushouya.order.service.api.impl;

import com.chushouya.order.dto.api.clerk.action.*;
import com.general.framework.core.exception.Ex;
import com.chushouya.order.constants.OrderActionEnum;
import com.chushouya.order.constants.OrderStatusEnum;
import com.chushouya.order.constants.PaymentMethodEnum;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.repository.OrderRepository;
//=====order.dto.api.clerk.action.*;
import com.chushouya.order.dto.api.clerk.action.*;
import com.chushouya.order.service.api.ClerkOrderActionApiService;
import com.chushouya.order.service.api.ClerkOrderActionCtrlApiService;
import com.chushouya.order.service.api.ClerkOrderQualityApiService;
import com.chushouya.order.service.common.CommonOrderActionService;
import com.chushouya.order.service.common.OrderLogService;
import com.chushouya.order.service.common.OrderPaymentService;
import com.general.framework.core.lang.Check;
import com.general.framework.core.lang.Dates;
import com.general.framework.core.lang.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Objects;

@Service
@Slf4j
public class ClerkOrderActionApiServiceImpl implements ClerkOrderActionApiService {

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private ClerkOrderActionCtrlApiService clerkOrderActionCtrlApiService;


    @Resource
    private OrderLogService orderLogService;

    @Resource
    private CommonOrderActionService commonOrderActionService;

    @Resource
    private ClerkOrderQualityApiService clerkOrderQualityApiService;

    @Resource
    private OrderPaymentService orderPaymentService;

    /**
     * 自定义收款方式渠道customize_pay_partner_list
     */
    private static final String CUSTOMIZE_PAY_PARTNER_LIST = "customize_pay_partner_list";


    private OrderEntity getOrder(Long orderId, Long clerkId) {
        final OrderEntity orderEntity = orderRepository.selectByPrimaryKey(orderId);
        Check.notNull(orderEntity, "订单不存在");
        Check.notFalse(Objects.equals(clerkId, orderEntity.getClerkId()), Strings.format("非法操作[业务员{}不可操作当前订单]", clerkId));
        return orderEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirm(ClerkConfirmAction confirm) {
        final OrderEntity orderEntity = this.getOrder(confirm.getOrderId(), confirm.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(confirm.getOrderAction(), orderEntity);

        commonOrderActionService.confirmOrder(orderEntity, confirm.getAppointStartTime(), confirm.getAppointEndTime(), Strings.format("确认订单 {}", Strings.defaultString(confirm.getRemark())), confirm.getOrderAction().toOrderStatus().value());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void accept(ClerkAcceptAction accept) {
        final OrderEntity orderEntity = this.getOrder(accept.getOrderId(), accept.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(accept.getOrderAction(), orderEntity);

        commonOrderActionService.acceptOrder(orderEntity, accept.getOrderAction().getActionName(), accept.getOrderAction().toOrderStatus().value());
    }

    @Override
//    @Transactional(rollbackFor = Exception.class)
    public void cancel(ClerkCancelAction cancel) {
        final OrderEntity orderEntity = this.getOrder(cancel.getOrderId(), cancel.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(cancel.getOrderAction(), orderEntity);

        commonOrderActionService.closeOrder(orderEntity, Strings.format("{} {}", cancel.getOrderAction().getActionName(), cancel.getCancelRemark()), cancel.getOrderAction().toOrderStatus().value());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void visit(ClerkVisitAction visit) {
        final OrderEntity orderEntity = this.getOrder(visit.getOrderId(), visit.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(visit.getOrderAction(), orderEntity);

        commonOrderActionService.visitOrder(orderEntity, visit.getOrderAction().getActionName(), visit.getOrderAction().toOrderStatus().value());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editOrder(ClerkEditOrderAction editOrder) {
        final OrderEntity orderEntity = this.getOrder(editOrder.getOrderId(), editOrder.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(editOrder.getOrderAction(), orderEntity);

        OrderEntity update = new OrderEntity();
        update.setOrderId(editOrder.getOrderId());
        update.setAppointStartTime(editOrder.getAppointStartTime());
        update.setAppointEndTime(editOrder.getAppointEndTime());
        update.setUpdateTime(Dates.getTimeNow());
        orderRepository.updateByPrimaryKeySelective(update);

        orderLogService.addOrderActionLog(editOrder.getOrderId(),
                OrderActionEnum.FOLLOW_ORDER.value(), Strings.format("{},原上门时间:[{}],备注:{}",
                        Strings.format("{} ~ {}", Dates.format(orderEntity.getAppointStartTime(), Dates.FMT_FULL_TIME), Dates.format(orderEntity.getAppointEndTime(), Dates.FMT_FULL_TIME)),
                        editOrder.getOrderAction().getActionName(),
                        Strings.defaultString(editOrder.getRemark(), "-")));
    }

    @Override
    public void complete(ClerkCompleteAction complete) {

        final OrderEntity orderEntity = this.getOrder(complete.getOrderId(), complete.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(complete.getOrderAction(), orderEntity);
        final Integer payType = complete.getPayType();
        final Long userId = orderEntity.getUserId();
        try {
            if (Objects.equals(payType, PaymentMethodEnum.ONLINE_ALIPAY.value())) {
                // 使用公共支付服务执行支付流程
                orderPaymentService.executeOrderPayment(orderEntity);

            } else if (Objects.equals(payType, PaymentMethodEnum.OFFLINE_PAYMENT.value())) {
                final BigDecimal completePrice = complete.getCompletePrice();
                final String msg = Strings.format("订单完成，收款方式:{} 成交价：{}元", PaymentMethodEnum.get(payType).named(), completePrice);
                commonOrderActionService.completeOrder(orderEntity, payType, completePrice, msg, OrderStatusEnum.COMPLETE.value());
            } else {
                throw Ex.business("不支持的收款方式");
            }
        }  catch (Exception e) {
            throw Ex.business("订单完成失败:{}", e.getMessage());
        }


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delivery(ClerkOrderDeliveryAction delivery) {
        delivery.getOrderIdList().forEach(orderId -> {
            final OrderEntity orderEntity = this.getOrder(orderId, delivery.getClerkId());
//            BaseOrderDTO baseOrderDTO = Beans.copy(orderEntity, BaseOrderDTO.class);
////            clerkOrderActionCtrlApiService.actionExecuteCheck(delivery.getOrderAction(), orderEntity);
//            //保存订单物流信息
//            orderLogisticsService.saveOrderLogistics(orderEntity.getOrderId(), baseOrderDTO.getBizType(), delivery.getExpressNo(), delivery.getExpressCompany(), LogisticsTypeEnum.CLERK_SEND.value(), "");
//            //更新订单物流状态
//            orderLogisticsService.saveOrderLogisticsStatus(baseOrderDTO, LogisticsTypeEnum.CLERK_SEND.value(), LogisticsStatusEnum.HAS_DELIVERY.value());

            orderLogService.addOrderActionLog(orderId,
                    OrderActionEnum.SEND_COMPANY.value(), Strings.format("{}:{},{}", delivery.getOrderAction().getActionName(), Strings.defaultString(delivery.getExpressCompany(), "普通快递"), delivery.getExpressNo()));
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitCollection(ClerkSubmitCollectionAction submitCollection) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitQuality(ClerkSubmitQualityAction submitQuality) {
        final Long orderId = submitQuality.getOrderId();
        final OrderEntity orderEntity = this.getOrder(submitQuality.getOrderId(), submitQuality.getClerkId());
        final Long partnerId = orderEntity.getPartnerId();
        clerkOrderActionCtrlApiService.actionExecuteCheck(submitQuality.getOrderAction(), orderEntity);
        clerkOrderQualityApiService.qualityOrder(orderEntity, submitQuality);

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitRemark(ClerkSubmitRemarkAction submitRemark) {
        final OrderEntity orderEntity = this.getOrder(submitRemark.getOrderId(), submitRemark.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(submitRemark.getOrderAction(), orderEntity);
        orderLogService.addOrderActionLog(submitRemark.getOrderId(),
                OrderActionEnum.FOLLOW_ORDER.value(), Strings.format("{}:{}", submitRemark.getOrderAction().getActionName(), submitRemark.getRemark()));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitUserCert(ClerkSubmitUserCertAction submitUserCert) {

    }

    @Override
    public void resetOrderStatus(ClerkResetOrderStatusAction resetOrderStatus) {
        final OrderEntity orderEntity = this.getOrder(resetOrderStatus.getOrderId(), resetOrderStatus.getClerkId());
        clerkOrderActionCtrlApiService.actionExecuteCheck(resetOrderStatus.getOrderAction(), orderEntity);

        commonOrderActionService.resetOrder(orderEntity, "", OrderStatusEnum.WAIT_CONFIRM.value());
    }


}
